package indicators

import (
	"fmt"
	"math"
)

// 价格数据结构
type PricePoint struct {
	Price     float64
	Timestamp int64
}

// 基础指标接口
type Indicator interface {
	Update(price float64) error
	GetValue() float64
	Reset()
}

// MA 均线指标
type MA struct {
	period    int
	prices    []float64
	currentMA float64
}

func NewMA(period int) *MA {
	return &MA{
		period: period,
		prices: make([]float64, 0, period),
	}
}

func (ma *MA) Update(price float64) error {
	ma.prices = append(ma.prices, price)
	if len(ma.prices) > ma.period {
		ma.prices = ma.prices[1:]
	}

	if len(ma.prices) < ma.period {
		return fmt.Errorf("insufficient data: need %d got %d", ma.period, len(ma.prices))
	}

	sum := 0.0
	for _, p := range ma.prices {
		sum += p
	}
	ma.currentMA = sum / float64(ma.period)
	return nil
}

func (ma *MA) GetValue() float64 {
	return ma.currentMA
}

func (ma *MA) Reset() {
	ma.prices = make([]float64, 0, ma.period)
	ma.currentMA = 0
}

// RSI 指标
type RSI struct {
	period     int
	gains      []float64
	losses     []float64
	lastPrice  float64
	currentRSI float64
}

func NewRSI(period int) *RSI {
	return &RSI{
		period:    period,
		gains:     make([]float64, 0, period),
		losses:    make([]float64, 0, period),
		lastPrice: 0,
	}
}

func (rsi *RSI) Update(price float64) error {
	if rsi.lastPrice == 0 {
		rsi.lastPrice = price
		return fmt.Errorf("initializing RSI")
	}

	change := price - rsi.lastPrice
	gain := math.Max(change, 0)
	loss := math.Max(-change, 0)

	rsi.gains = append(rsi.gains, gain)
	rsi.losses = append(rsi.losses, loss)

	if len(rsi.gains) > rsi.period {
		rsi.gains = rsi.gains[1:]
		rsi.losses = rsi.losses[1:]
	}

	if len(rsi.gains) < rsi.period {
		return fmt.Errorf("insufficient data: need %d got %d", rsi.period, len(rsi.gains))
	}

	avgGain := average(rsi.gains)
	avgLoss := average(rsi.losses)

	if avgLoss == 0 {
		rsi.currentRSI = 100
	} else {
		rs := avgGain / avgLoss
		rsi.currentRSI = 100 - (100 / (1 + rs))
	}

	rsi.lastPrice = price
	return nil
}

func (rsi *RSI) GetValue() float64 {
	return rsi.currentRSI
}

func (rsi *RSI) Reset() {
	rsi.gains = make([]float64, 0, rsi.period)
	rsi.losses = make([]float64, 0, rsi.period)
	rsi.lastPrice = 0
	rsi.currentRSI = 0
}

func average(values []float64) float64 {
	if len(values) == 0 {
		return 0
	}
	sum := 0.0
	for _, v := range values {
		sum += v
	}
	return sum / float64(len(values))
}
